/**
  * @file    :graph.hpp
  * @brief   :图的模板类
  * @author  :TMJ
  * @version :V1.0.0
  * @date    :2023-12-30
*/

#ifndef GRAPH_GRAPH_H_
#define GRAPH_GRAPH_H_

#include <iostream>
#include <vector>

// 边模板类
template<typename vertexType, typename weightType>
class Edge {
public:
    vertexType _start; // 起点
    vertexType _end;   // 终点
    weightType _weight;// 权值

    // 无参构造函数
    Edge() : _start(vertexType()), _end(vertexType()), _weight(weightType()) {}

    // 有参构造函数
    Edge(const vertexType &start, const vertexType &end, const weightType &weight)
        : _start(start), _end(end), _weight(weight) {}

    // 重载 <= 运算符
    bool operator<=(const Edge<vertexType, weightType> &edge) {
        return this->_weight <= edge._weight;
    }

    // 重载 < 运算符
    bool operator<(const Edge<vertexType, weightType> &edge) {
        return this->_weight < edge._weight;
    }

    // 重载 >= 运算符
    bool operator>=(const Edge<vertexType, weightType> &edge) {
        return this->_weight >= edge._weight;
    }

    // 重载 > 运算符
    bool operator>(const Edge<vertexType, weightType> &edge) {
        return this->_weight > edge._weight;
    }
};

// 图的抽象模板类
template<typename vertexType, typename weightType>
class Graph {
protected:
    int _type;          // 图类型
    int _vertexCount;   // 顶点数量
    int _edgeCount;     // 边数量
    int _maxVertexCount;// 最大顶点数

    std::vector<int> *_degree;   // 度（无向图使用）
    std::vector<int> *_outDegree;// 出度（有向图使用）
    std::vector<int> *_inDegree; // 入度（有向图使用）

public:
    static const int DIRECTED = 1;  // 有向图类型
    static const int UNDIRECTED = 2;// 无向图类型

    // 获取图的类型
    int getType() const {
        return this->_type;
    }

    // 获取边的数量
    int getEdgeCount() const {
        return this->_edgeCount;
    }

    // 获取顶点数量
    int getVertexCount() const {
        return this->_vertexCount;
    }

    // 获取顶点的索引
    virtual int getVertexIndex(const vertexType &vertex) const = 0;

    // 通过索引获取顶点
    virtual bool getVertex(int index, vertexType &vertex) const = 0;

    // 获取边权值
    virtual bool getEdgeWeight(const vertexType &start, const vertexType &end, weightType &weight) const = 0;

    // 通过顶点索引获取权值
    virtual bool getEdgeWeightByIndex(int startIndex, int endIndex, weightType &weight) const = 0;

    // 插入顶点
    virtual bool insertVertex(const vertexType &vertex) = 0;

    // 插入边
    virtual bool insertEdge(const vertexType &start, const vertexType &end, const weightType &weight) = 0;

    // 删除顶点
    virtual bool removeVertex(const vertexType &vertex) = 0;

    // 删除边
    virtual bool removeEdge(const vertexType &start, const vertexType &end) = 0;
};


#endif// GRAPH_GRAPH_H_